/**
 * @brief	PWM控制
 * @details	基于STM30G030  LL库使用
 * @author	XXX
 * @date	2024-01-30 13:16
 * @version	v1.4
 * @file    Bsp_Port\bsp_PWM.c
 * @par History:
 *	v1.3: 蔡正祥, 2024-01-03, 增加函数bsp_PWM_Set_Hz()\n
 *	v1.4: 蔡正祥, 2024-01-30, 占空比变成float类型\n
 *	v1.5: 蔡正祥, 2024-04-23, 将malloc()去除、修复一些Bug\n
 */
#include "bsp_PWM.h"
#include "stdlib.h"

/*  @brief  新建一个 PWM 对象
    @param  *tim
            选择所用MCU的定时器 例如:TIM1
    @param  Channel
            选择所用MCU的定时器通道 例如:LL_TIM_CHANNEL_CH1
    @param  hz
            频率(0.2HZ~100 000HZ)
    @param  pulse
            占空比%
    @param  state
            运行状态 p_STOP  p_RUN
    @return PWM结构体
    @property 无
*/
PWM_t bsp_PWM_Obj_New(TIM_TypeDef *tim, uint32_t Channel, float hz, float pulse, pwm_t state)
{
    // PWM_t *new_obj = malloc(sizeof(PWM_t));

    PWM_t new_obj = {
        .p_Mcu.p_TIMx = tim,
        .p_Mcu.p_CHANNEL_CHx = Channel,
        .p_Hz = hz,
        .p_Pulse = pulse,
        .p_State = state,
    };

    if (hz >= 100)
    {
        new_obj.p_Mcu.p_ARR = 64;
    }
    else if (hz > 0.20)
    {
        new_obj.p_Mcu.p_ARR = 6400;
    }
    else
    {
        hz = 0.20;
        new_obj.p_Mcu.p_ARR = 6400;
    }

    new_obj.p_Mcu.p_PSC = (uint16_t)(64000000 / (hz * new_obj.p_Mcu.p_ARR)); // 64000 000HZ
    new_obj.p_Cycle_ms = (1.0 / hz) * 1000.0;

    // new_obj.p_Hz = hz;
    // new_obj.p_Pulse = pulse;
    // new_obj.p_State = state;

    LL_TIM_SetPrescaler(new_obj.p_Mcu.p_TIMx, new_obj.p_Mcu.p_PSC - 1);  // 可编程预分频器PCS
    LL_TIM_SetAutoReload(new_obj.p_Mcu.p_TIMx, new_obj.p_Mcu.p_ARR - 1); // 设置自动重装载寄存器ARR（电机运行速度）（周期）

    bsp_PWM_Set_Pulse(&new_obj, new_obj.p_Pulse); // 占空比

    LL_TIM_EnableAllOutputs(new_obj.p_Mcu.p_TIMx); // 使能输出(设置TIMx_BDTR寄存器中的MOE位)
    LL_TIM_EnableCounter(new_obj.p_Mcu.p_TIMx);

    if (state == p_RUN) // 是否启动
        bsp_PWM_Set_Run(&new_obj);
    else if (state == p_STOP)
        bsp_PWM_Set_Stop(&new_obj);

    return new_obj;
}
/*  @brief  设置占空比
    @param  *obj
            对象
    @param  value
            值  例如占比50%，就写50
    @return 无
    @property 无
*/
void bsp_PWM_Set_Pulse(PWM_t *obj, float value)
{
    uint32_t CHx_CCR = 0;
    if (value <= 100)
    {
        CHx_CCR = (uint16_t)(value * obj->p_Mcu.p_ARR / 100.0);
    }
    else
    {
        CHx_CCR = (uint16_t)(100 * obj->p_Mcu.p_ARR / 100.0);
    }
    obj->p_Mcu.p_PSC = CHx_CCR;
    obj->p_Pulse = value;

    switch (obj->p_Mcu.p_CHANNEL_CHx)
    {
    case LL_TIM_CHANNEL_CH1:
        LL_TIM_OC_SetCompareCH1(obj->p_Mcu.p_TIMx, CHx_CCR);
        break;
    case LL_TIM_CHANNEL_CH2:
        LL_TIM_OC_SetCompareCH2(obj->p_Mcu.p_TIMx, CHx_CCR);
        break;
    case LL_TIM_CHANNEL_CH3:
        LL_TIM_OC_SetCompareCH3(obj->p_Mcu.p_TIMx, CHx_CCR);
        break;
    case LL_TIM_CHANNEL_CH4:
        LL_TIM_OC_SetCompareCH4(obj->p_Mcu.p_TIMx, CHx_CCR);
        break;
    case LL_TIM_CHANNEL_CH5:
        LL_TIM_OC_SetCompareCH5(obj->p_Mcu.p_TIMx, CHx_CCR);
        break;
    case LL_TIM_CHANNEL_CH6:
        LL_TIM_OC_SetCompareCH6(obj->p_Mcu.p_TIMx, CHx_CCR);
        break;
    default:
        break;
    }
}
/*  @brief  设置频率
    @param  *obj
            对象
    @param  value
            频率
    @return 无
    @property 无
*/
void bsp_PWM_Set_Hz(PWM_t *obj, float value)
{
    if (value >= 100)
    {
        obj->p_Mcu.p_ARR = 64;
    }
    else if (value > 0.20)
    {
        obj->p_Mcu.p_ARR = 6400;
    }
    else
    {
        if (value != 0)
        {
            value = 0.20;
            obj->p_Mcu.p_ARR = 6400;
        }
        else
        {
            obj->p_Hz = 0;
            obj->p_Cycle_ms = 0;
            obj->p_Mcu.p_PSC = 1;
            obj->p_Mcu.p_ARR = 1;
            // obj->p_Pulse = 0;
            // bsp_PWM_Set_Stop(obj);
            goto label;
        }
    }

    obj->p_Mcu.p_PSC = (uint16_t)(64000000 / (value * obj->p_Mcu.p_ARR)); // 64000 000HZ
    obj->p_Cycle_ms = (1.0 / value) * 1000.0;

    obj->p_Hz = value;
    // obj->p_Pulse = pulse;
    // obj->p_State = state;
label:
    LL_TIM_SetPrescaler(obj->p_Mcu.p_TIMx, obj->p_Mcu.p_PSC - 1);  // 可编程预分频器PCS
    LL_TIM_SetAutoReload(obj->p_Mcu.p_TIMx, obj->p_Mcu.p_ARR - 1); // 设置自动重装载寄存器ARR（电机运行速度）（周期）

    bsp_PWM_Set_Pulse(obj, obj->p_Pulse); // 占空比

    LL_TIM_EnableAllOutputs(obj->p_Mcu.p_TIMx); // 使能输出(设置TIMx_BDTR寄存器中的MOE位)
    LL_TIM_EnableCounter(obj->p_Mcu.p_TIMx);

    pwm_t state = obj->p_State;
    if (state == p_RUN) // 是否启动
        bsp_PWM_Set_Run(obj);
    else if (state == p_STOP)
        bsp_PWM_Set_Stop(obj);
}
/*  @brief  PWM运行
    @param  *obj
            PWM 对象
    @return 无
    @property 无
*/
void bsp_PWM_Set_Run(PWM_t *obj)
{
    obj->p_State = p_RUN;
    LL_TIM_CC_EnableChannel(obj->p_Mcu.p_TIMx, obj->p_Mcu.p_CHANNEL_CHx); // 使能通道
    LL_TIM_EnableIT_UPDATE(obj->p_Mcu.p_TIMx);
}
/*  @brief  PWM停止
    @param  *obj
            PWM 对象
    @return 无
    @property 无
*/
void bsp_PWM_Set_Stop(PWM_t *obj)
{
    obj->p_State = p_STOP;
    LL_TIM_CC_DisableChannel(obj->p_Mcu.p_TIMx, obj->p_Mcu.p_CHANNEL_CHx); // 禁用
    LL_TIM_DisableIT_UPDATE(obj->p_Mcu.p_TIMx);
}
/*  @brief  获取PWM的运行状态
    @param  *obj
            PWM 对象
    @return 0停止、1运行
    @property 无
*/
pwm_t bsp_PWM_Get_State(PWM_t *obj)
{
    return obj->p_State;
}

PWM_t MOTOR_IN1;
PWM_t MOTOR_IN2;
PWM_t MOTOR_IN3;
// PWM调试s
void bsp_PWM_Debug(void)
{
    MOTOR_IN1 = bsp_PWM_Obj_New(BEEP_IN1_GPIO, 1000, 70, p_RUN);
    // MOTOR_IN2 = bsp_PWM_Obj_New(MOTOR_IN2_GPIO, 1000, 50, p_RUN);
    // MOTOR_IN3 = bsp_PWM_Obj_New(MOTOR_IN3_GPIO, 1000, 50, p_RUN);

    while (1)
    {
    }
}
